package com.learn.intercecptor;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.RowBounds;

import java.sql.Connection;
import java.util.Map;

/**
 * @author: liyf
 * @create: 2025-02-15 22:28
 **/
@Intercepts({
        @Signature(
                type = StatementHandler.class,
                method = "prepare",
                args = {Connection.class, Integer.class}
        )
})
public class PaginationAndSortInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        BoundSql boundSql = statementHandler.getBoundSql();
        MappedStatement mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(statementHandler, "mappedStatement");
        String sql = boundSql.getSql();

        // 获取分页参数
        RowBounds rowBounds = (RowBounds) ReflectUtil.getFieldValue(statementHandler, "rowBounds");
        if (rowBounds != RowBounds.DEFAULT) {
            int offset = rowBounds.getOffset();
            int limit = rowBounds.getLimit();
            sql = getPaginationSql(sql, offset, limit);
        }

        // 获取排序参数
        Object parameter = boundSql.getParameterObject();
        if (parameter instanceof Map) {
            Map<?, ?> paramMap = (Map<?, ?>) parameter;
            String sortField = (String) paramMap.get("sortField");
            String sortOrder = (String) paramMap.get("sortOrder");

            if (sortField != null && sortOrder != null) {
                sql = getSortSql(sql, sortField, sortOrder);
            }
        }

        // 将修改后的 SQL 设置回 BoundSql
        ReflectUtil.setFieldValue(boundSql, "sql", sql);

        return invocation.proceed();
    }

    /**
     * 生成分页 SQL
     */
    private String getPaginationSql(String sql, int offset, int limit) {
        return sql + " LIMIT " + offset + ", " + limit;
    }

    /**
     * 生成排序 SQL
     */
    private String getSortSql(String sql, String sortField, String sortOrder) {
        return sql + " ORDER BY " + sortField + " " + sortOrder;
    }
}
